package com.datalayer.utils.builder;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Georgiana.Scarlat
 * Date: 7/9/12
 * Time: 11:25 AM
 */
public class ObjectBuilder implements Builder {

    private Method m;
    private Object object;
    private Object source;

    public ObjectBuilder(Method m, Object object, Object source) {
        this.m = m;
        this.object = object;
        this.source = source;
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> getONE2ONE() throws UnsupportedOperationException {
        List<T> result = new LinkedList<T>();
        T obj;
        try {

            m.setAccessible(true);
            obj = (T) m.invoke(object);

        } catch (IllegalAccessException e) {
            throw new UnsupportedOperationException("Can't invoke private method " + m.getName(), e);
        } catch (InvocationTargetException e) {
            throw new UnsupportedOperationException("Method " + m.getName() + " throws an exception", e);
        }
        if (obj != null && !obj.equals(source)) {
            result.add(obj);
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> getMANY2ONE() throws UnsupportedOperationException {
        List<T> result = new LinkedList<T>();
        Collection collection;
        try {
            collection = (Collection) m.invoke(object);
        } catch (IllegalAccessException e) {
            throw new UnsupportedOperationException("Can't invoke private method " + m.getName(), e);
        } catch (InvocationTargetException e) {
            throw new UnsupportedOperationException("Method " + m.getName() + " throws an exception", e);
        }
        for (Object o : collection) {
            if (o != null && !o.equals(source)) {

                result.add((T) o);
            }

        }
        return result;
    }


}
